package com.toobigtofail.entities
{
	import com.toobigtofail.drum.DrumListener;
	import com.toobigtofail.drum.HitResult;
	import com.toobigtofail.drum.Notes;
	import com.toobigtofail.drum.Pattern;
	
	import net.flashpunk.Entity;
	import net.flashpunk.graphics.Graphiclist;
	import net.flashpunk.graphics.Text;
	
	public class DrumBeatDisplay extends Entity
	{
		private var _drumListener:DrumListener = new DrumListener;
		private var _patterns:Array = new Array();
		
		private var _bpm:Number = 60;
		
		public function DrumBeatDisplay(x:Number=0, y:Number=0) {
			this.x = x;
			this.y = y;
			
			graphic = new Graphiclist();
		}
		
		override public function added():void {
			super.added();
			
			_drumListener.start();
		}
		
		override public function update():void {
			super.update();
			
			// Apply all of the drums that were hit this frame to all patterns
			var drumsHit:Array = _drumListener.getDrumsHit();
			for each (var drumHit:int in drumsHit) {
				//trace("hit drum " + Notes.toString(Notes.getNote(drumHit)));
				drum(drumHit);
			}
			
			// Display all of the active patterns, by scrolling the next note of each along the screen
			(graphic as Graphiclist).removeAll();
			var yOffset:int = 0;
			for each (var pattern:Pattern in _patterns) {
				if (pattern.active) {
					var display:String = Notes.toString(pattern.nextNote);
					var nextNextNote:int = pattern.getNote(1);
					if (nextNextNote != Notes.INVALID) {
						display += " - " + Notes.toString(nextNextNote);
					}
					var patternDisplay:Text = new Text(display, x, y + yOffset);
					(graphic as Graphiclist).add(patternDisplay);
				}
				yOffset += 15;
			}
		}
		
		public function drum(key:int):void {
			var activePatterns:int = _patterns.length;
			for each (var pattern:Pattern in _patterns) {
				if (pattern.active) {
					var hitResult:HitResult = pattern.checkNextNote(key);
					
					if (hitResult.result == HitResult.FAILURE) {
						pattern.stop();
					}
					else if (hitResult.result == HitResult.PATTERN_SUCCESS) {
						resetPatterns();
						break;
					}
				} 
				else {
					activePatterns--;
				}
			}
			
			if (!activePatterns) {
				resetPatterns();
			}
		}
		
		public function setDrums(...notes):Vector.<int> {
			var notesVec:Vector.<int> = Vector.<int>(notes);
			_drumListener.setDrums(notesVec);
			return notesVec;
		}
		
		public function addPattern(patternString:String):void {
			var pattern:Pattern = new Pattern(patternString, _bpm);
			
			_patterns.push(pattern);
			pattern.start();
		}
		
		public function resetPatterns():uint {
			for each (var pattern:Pattern in _patterns) {
				pattern.stop();
				pattern.start();
			}
			return _patterns.length;
		}
	}
}